//-------------------------------------------------------------------------
// File: mru_list.hpp
//
// Descr.: - todo -
//
// Author: Stefan Leihkauf
// Date:   30.05.2012
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
/**
	constructor
*/
template<typename ItemType>
mru_list<ItemType>::mru_list() :
	_mru_list_max_items(MRULIST_MAX_ITEMS)
{
}

//-------------------------------------------------------------------------
/**
	constructor

	@param capacity - initial capacity of list
*/
template<typename ItemType>
mru_list<ItemType>::mru_list(const unsigned capacity) :
	_mru_list_max_items(capacity)
{
	if(_mru_list_max_items == 0)
		_mru_list_max_items = MRULIST_MAX_ITEMS;
}

//-------------------------------------------------------------------------
/**
	get capacity
*/
template<typename ItemType>
unsigned mru_list<ItemType>::capacity() const
{
	return _mru_list_max_items;
}

//-------------------------------------------------------------------------
/**
	set capacity
*/
template<typename ItemType>
void mru_list<ItemType>::set_capacity(unsigned capacity)
{
	if(capacity == 0)
		capacity = MRULIST_MAX_ITEMS;

	while(size() > capacity)
		_mru_list.pop_back();

	_mru_list_max_items = capacity;
}

//-------------------------------------------------------------------------
/**
	get actual size
*/
template<typename ItemType>
unsigned mru_list<ItemType>::size() const
{
	return _mru_list.size();
}

//-------------------------------------------------------------------------
/**
	get iterator to begin of list
*/
template<typename ItemType>
typename mru_list<ItemType>::iterator mru_list<ItemType>::begin()
{
	return _mru_list.begin();
}

//-------------------------------------------------------------------------
/**
	get const iterator to begin of list
*/
template<typename ItemType>
typename mru_list<ItemType>::const_iterator mru_list<ItemType>::begin() const
{
	return _mru_list.cbegin();
}

//-------------------------------------------------------------------------
/**
	get iterator to end of list
*/
template<typename ItemType>
typename mru_list<ItemType>::iterator mru_list<ItemType>::end()
{
	return _mru_list.end();
}

//-------------------------------------------------------------------------
/**
	get const iterator to end of list
*/
template<typename ItemType>
typename mru_list<ItemType>::const_iterator mru_list<ItemType>::end() const
{
	return _mru_list.cend();
}

//-------------------------------------------------------------------------
/**
	add item to list (if unique)
*/
template<typename ItemType>
void mru_list<ItemType>::add(const ItemType& val)
{
	iterator iter = this->find(val);
	if(iter != this->end())
		_mru_list.erase(iter);

	if(size() == capacity())
		_mru_list.pop_back();

	_mru_list.insert(_mru_list.begin(), val);
}

//-------------------------------------------------------------------------
/**
	erase item from list
*/
template<typename ItemType>
void mru_list<ItemType>::erase(iterator where)
{
	_mru_list.erase(where);
}

//-------------------------------------------------------------------------
/**
	erase item from list (const version)
*/
template<typename ItemType>
void mru_list<ItemType>::erase(const ItemType& what)
{
	iterator iter = this->begin();
	while(iter != this->end()) {
		if((*iter) == what) {
			_mru_list.erase(iter);
			return;
		}
		++iter;
	}
}

//-------------------------------------------------------------------------
/**
	clear list
*/
template<typename ItemType>
void mru_list<ItemType>::clear()
{
	_mru_list.clear();
}

//-------------------------------------------------------------------------
/**
	find item in list (internal)
*/
template<typename ItemType>
typename mru_list<ItemType>::iterator mru_list<ItemType>::find(const ItemType& what)
{
	iterator iter = this->begin();
	while(iter != this->end()) {
		if((*iter) == what)
			return iter;
		++iter;
	}
	return this->end();
}

//-------------------------------------------------------------------------
/**
	indexed access operator (read only)
*/
template<typename ItemType>
const ItemType& mru_list<ItemType>::operator [] (const unsigned i) const
{
	assert(i < _mru_list.size());
	return _mru_list[i];
}
